package edu.bmstu.rslab;

import java.awt.*;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;

/**
 * Created by Chikh (using IntelliJ IDEA).
 * Date: 05.03.2009
 * Time: 13:21:30
 */
public class Detector {

    public void setMask(BufferedImage diode) {

        long sumRed = 0, sumGreen = 0, sumBlue = 0;
        for (int i = 0; i < diode.getWidth(); i++)
            for (int j = 0; j < diode.getHeight(); j++) {
                Color color = new Color(diode.getRGB(i, j));
                sumRed += color.getRed();
                sumGreen += color.getGreen();
                sumBlue += color.getBlue();
            }
        thresholdR = (double)sumRed / (double)(diode.getWidth() * diode.getHeight());
        thresholdG = (double)sumGreen / (double)(diode.getWidth() * diode.getHeight());
        thresholdB = (double)sumBlue / (double)(diode.getWidth() * diode.getHeight());

        double distanceSquareSum = 0;
        for (int i = 0; i < diode.getWidth(); i++)
            for (int j = 0; j < diode.getHeight(); j++) {
                Color color = new Color(diode.getRGB(i, j));
                distanceSquareSum += (color.getRed() - thresholdR)*(color.getRed() - thresholdR) +
                        (color.getGreen() - thresholdG)*(color.getGreen() - thresholdG) +
                        (color.getBlue() - thresholdB)*(color.getBlue() - thresholdB);
            }

        dispersion = distanceSquareSum / (double)(diode.getWidth() * diode.getHeight()); 
    }

    public Point2D detect(BufferedImage image) {

        int iBegin, iEnd, jBegin, jEnd;
        if (detectedPosition != null) {
            iBegin = (int)Math.round(detectedPosition.getX() - image.getWidth()/10);
            iEnd = (int)Math.round(detectedPosition.getX() + image.getWidth()/10);
            jBegin = (int)Math.round(detectedPosition.getY() - image.getHeight()/10);
            jEnd = (int)Math.round(detectedPosition.getY() + image.getHeight()/10);
        }
        else {
            iBegin = 0;
            iEnd = image.getWidth();
            jBegin = 0;
            jEnd = image.getHeight();
        }
        double maximum = 0;
        int maximumXLocation = 0, maximumYLocation = 0;
        for (int i = iBegin; i < iEnd; i++)
            for (int j = jBegin; j < jEnd; j++) {
                Color colorImage = new Color(image.getRGB(i, j));
                double filteredPixelValue = Math.exp(-((colorImage.getRed() - thresholdR)*(colorImage.getRed() - thresholdR) +
                (colorImage.getGreen() - thresholdG)*(colorImage.getGreen() - thresholdG) +
                (colorImage.getBlue() - thresholdB)*(colorImage.getBlue() - thresholdB)) / dispersion);
                if (maximum < filteredPixelValue) {
                    maximum = filteredPixelValue;
                    maximumXLocation = i;
                    maximumYLocation = j;
                }
            }
        detectedPosition = new Point2D.Double((double)maximumXLocation, (double)maximumYLocation);
        return detectedPosition;
    }

    private double thresholdR;
    private double thresholdG;
    private double thresholdB;
    private double dispersion;
    private Point2D detectedPosition;
}